/**
 * 2025/01/01 - 2025/12/31
 */
package com.snail.server.database.engine.ddl.holder;

import com.snail.server.database.engine.ddl.model.table.TableAlter;
import com.snail.server.database.engine.ddl.model.table.TableCreate;
import com.snail.server.database.engine.ddl.operation.IDDLOperation;
import com.snail.starter.commons.exception.BizException;
import com.snail.server.database.engine.datasource.enums.DataSourceTypeEnum;
import com.snail.server.database.engine.datasource.holder.DynamicDatasourceHolder;
import com.snail.server.database.engine.error.DatabaseEngineErrorCode;
import com.snail.starter.db.enums.EnableOrDisEnableEnum;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @author zgadmin
 * @date 2025/8/29 14:53
 */
@Component
public class DDLHolder {

    @Resource
    ApplicationContext applicationContext;

    @Resource
    DynamicDatasourceHolder dynamicDatasourceHolder;

    public boolean createTable(Long datasourceId, TableCreate tableCreate) {
        return getInterface(datasourceId)
                .createTable(datasourceId, tableCreate);
    }

    public boolean alterTable(Long datasourceId, TableAlter tableAlter) {
        return getInterface(datasourceId)
                .alterTable(datasourceId, tableAlter);
    }

    public boolean dropTable(Long datasourceId, String tableName) {
        return getInterface(datasourceId)
                .dropTable(datasourceId, tableName);
    }

    public IDDLOperation getInterface(Long datasourceId) {
        DataSourceTypeEnum datasourceType = dynamicDatasourceHolder.getDataSourceType(datasourceId, EnableOrDisEnableEnum.ENABLE);
        if (null == datasourceType) {
            throw BizException.of(DatabaseEngineErrorCode.MISS_DATASOURCE_TYPE);
        }
        Map<String, IDDLOperation> iddlOperationMap = applicationContext.getBeansOfType(IDDLOperation.class);
        if (null == iddlOperationMap || iddlOperationMap.isEmpty()) {
            throw BizException.of(DatabaseEngineErrorCode.MISS_DDL_OPERATION_IMPL, new Object[]{datasourceType.getDesc()});
        }
        return iddlOperationMap.values().stream()
                .filter(iddlOperation -> iddlOperation.support(datasourceType))
                .findFirst()
                .orElseThrow(() -> BizException.of(DatabaseEngineErrorCode.MISS_DDL_OPERATION_IMPL, new Object[]{datasourceType.getDesc()}));
    }
}